<template>
  <div>
    <el-dialog v-model="articleStore.articleFormVisible" title="发布文章" width="35%" @close="diaLogClose">
      <el-form :model="articleInfo" status-icon label-width="120px" @submit.prevent :rules="rules" :validate-on-rule-change="false" ref="articleRef">
        <!-- 文章 标题 -->
        <el-form-item label="文章标题" prop="article_title">
          <el-input v-model="articleInfo.article_title" autocomplete="off" />
        </el-form-item>
        <!-- 文章 标签 -->
        <el-form-item label="文章标签" prop="article_label">
          <div class="labels">
            <el-tag
              v-for="tag in articleInfo.article_label"
              :key="tag.id"
              class="mx-1"
              closable
              :disable-transitions="false"
              @close="handleClose(tag)"
              size="large"
            >
              {{ tag.label_name }}
            </el-tag>
          </div>
          <el-input
            v-if="inputVisible"
            ref="InputRef"
            v-model="inputValue"
            class="ml-1 w-20"
            @keyup.enter="handleInputConfirm"
            @blur="handleInputConfirm"
          />
          <el-button v-else class="button-new-tag ml-1" @click="showInput"> + New Tag </el-button>
          <ul class="showTags">
            <li v-for="item in labels" :key="item.id" @click="handleTagClick(item)">{{ item.label_name }}</li>
          </ul>
        </el-form-item>
        <!-- 文章 类型 -->
        <el-form-item label="文章类型" prop="article_type">
          <el-select v-model="articleInfo.article_type">
            <el-option v-for="item in types" :key="item['id']" :label="item['type_name']" :value="item['id']" />
          </el-select>
        </el-form-item>
        <!-- 上传封面 -->
        <el-form-item label="上传封面" prop="article_cover">
          <el-upload
            ref="uploadCover"
            action="#"
            :auto-upload="false"
            :http-request="uploadAction"
            :before-upload="beforeUpload"
            :before-remove="beforeRemove"
            :on-change="handleChangePic"
            list-type="picture"
            drag
          >
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">Drop file here or <em>click to upload</em></div>
            <template #tip>
              <div class="el-upload__tip">jpg/jpeg/png files with a size less than 3mb</div>
            </template>
          </el-upload>
        </el-form-item>
        <!-- 置顶 -->
        <el-form-item label="置顶">
          <el-switch v-model="articleInfo.is_sticky" />
        </el-form-item>
        <!-- 推荐 -->
        <el-form-item label="推荐">
          <el-switch v-model="articleInfo.is_recommend" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="articleStore.articleVisibleController(false)">取消</el-button>
          <el-button type="primary" @click="onSubmitArticle(articleRef)"> 发表 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup name="releaseDialog">
  import { UploadFilled } from '@element-plus/icons-vue'
  import type { UploadProps, UploadInstance, FormRules, FormInstance, ElInput } from 'element-plus'
  import { reactive, ref, nextTick } from 'vue'
  import useArticleStore from '@/store/article'
  import notification from '@/utils/notification'
  import { uploadCoverRequest, uploadArticleRequest } from '@/network/api/article-api'
  import { addLabelRequest } from '@/network/api/label-api'
  const articleStore = useArticleStore()
  const emit = defineEmits(['uploadArticleSucceed'])
  const props = defineProps<{
    mdContent: string
    types: any
    labels: any
  }>()
  interface IArticle {
    article_title: string
    article_label: any[]
    article_type: number
    is_sticky: boolean
    is_recommend: boolean
  }
  const articleInfo = reactive<IArticle>({
    article_title: '',
    article_label: [],
    article_type: 1,
    is_sticky: false,
    is_recommend: false,
  })
  let articleId = ref<number>(0)
  // 表单ref对象
  const articleRef = ref<FormInstance>()
  // 表单 校验规则
  const rules = reactive<FormRules>({
    article_title: [
      { required: true, message: '标题为必填项~', trigger: 'change' },
      { min: 3, max: 40, message: '标题长度在3-40个字符~', trigger: 'change' },
    ],
    article_label: [
      {
        required: true,
        message: '标签为必选项~',
        trigger: 'change',
      },
    ],
    article_type: [
      {
        required: true,
        message: '类型为必选项~',
        trigger: 'change',
      },
    ],
    article_cover: [
      {
        required: true,
        message: '封面为必传项~',
        trigger: 'change',
      },
    ],
  })
  // 上传组件ref对象
  const uploadCover = ref<UploadInstance>()
  const inputValue = ref<string>()
  const inputVisible = ref<boolean>()
  const InputRef = ref<InstanceType<typeof ElInput>>()
  const handleInputConfirm = async () => {
    if (inputValue.value) {
      const rusult = await addLabelRequest(inputValue.value)
      articleInfo.article_label.push({ id: rusult.result.insertId, label_name: inputValue.value })
    }
    inputVisible.value = false
    inputValue.value = ''
  }

  const showInput = () => {
    inputVisible.value = true
    nextTick(() => {
      InputRef.value!.input!.focus()
    })
  }

  const handleClose = (tag: any) => {
    const index = articleInfo.article_label.findIndex(item => item.id === tag.id)
    articleInfo.article_label.splice(index, 1)
  }

  const handleTagClick = (item: any) => {
    if (!articleInfo.article_label.some(ele => ele.id === item.id)) {
      articleInfo.article_label.push(item)
    }
  }

  const diaLogClose = () => {
    rules.article_cover = [
      {
        required: true,
        message: '封面为必传项~',
        trigger: 'change',
      },
    ]
    articleRef.value?.resetFields()
    uploadCover.value?.clearFiles()
  }
  // 上传图片之前的回调，限制上传大小和上传类型
  const beforeUpload: UploadProps['beforeUpload'] = rawFile => {
    const type = ['image/jpeg', 'image/jpg', 'image/png']
    if (type.indexOf(rawFile.type) === -1) {
      notification.warning('文章封面图片类型必须是以下格式：JPG/JPEG/PNG format!')
      return false
    } else if (rawFile.size / 1024 / 1024 > 3) {
      notification.error('图片大小不能超过 3MB!')
      return false
    }
    return true
  }
  // 限制图片数量
  //限制只上传一个文件
  const handleChangePic = (file: any, fileList: any) => {
    if (fileList.length > 1) {
      fileList.splice(0, 1)
    }
    articleRef.value?.clearValidate('article_cover')
    rules.article_cover = []
  }
  // 删除图片事件
  const beforeRemove = () => {
    rules.article_cover = [
      {
        required: true,
        message: '封面为必传项~',
        trigger: 'change',
      },
    ]
  }
  // 上传封面
  const uploadAction = async (param: any) => {
    // console.log('在这里上传封面')
    // console.log(articleStore.article_id)
    const { file } = param
    const formData = new FormData()
    formData.append('cover', file)
    const result = await uploadCoverRequest(formData, articleId.value)
    notification.success(result.msg)
    articleStore.articleVisibleController(false)
    // 清空mdContent
    emit('uploadArticleSucceed')
    // 清空articleInfo
    articleInfo.article_title = ''
    articleInfo.article_label = []
    articleInfo.article_type = 0
    articleInfo.is_recommend = false
    articleInfo.is_sticky = false
  }
  // 上传文章
  const articleUpload = async () => {
    const result = await uploadArticleRequest(props.mdContent, articleInfo)
    articleId.value = result.result.article_id
  }
  const onSubmitArticle = async (formEl: FormInstance | undefined) => {
    console.log(articleInfo)

    if (!formEl) return
    await formEl.validate(async (valid, fields) => {
      if (valid) {
        // 先上传文章 获得article_id
        await articleUpload()
        // 再上传封面
        uploadCover.value?.submit()
      } else {
        return
      }
    })
  }
  defineExpose({ uploadCover, uploadAction })
</script>

<style lang="less" scoped>
  .showTags {
    display: flex;
    flex-wrap: wrap;
    list-style: none;
    margin-top: 20px;
    height: auto;

    li {
      margin: 3px 5px;
      padding: 1px 6px;
      border-radius: 5px;
      font-size: 14px;
      border: 1px dashed #409eff;
      cursor: pointer;
    }
  }

  .labels {
    display: flex;
    flex-wrap: wrap;

    .el-tag {
      margin: 0 4px;
      margin-bottom: 3px;
    }
  }
</style>
